package cn.csq.threaddemo;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @author csq
 * @version 1.0.0
 * @ClassName CreateTheadDemo3.java
 * @Description TODO
 * @createTime 2021年12月07日 22:48:00
 */
public class CreateTheadDemo3 {
    //继承Thread类或者实现Runnable接口这两种方式来 创建线程类，但是这两种方式有一个共同的缺陷：不能获取异步执行的 结果。


    //通过Callable接口和FutureTask类相结合创建线 程。

    //Callable接口同Runnable接口是没有直接关系的，它们通过RunnableFuture 桥接接口完成

    //Future 接口 三大功能

    //（1）能够取消异步执行中的任务。 （2）判断异步任务是否执行完成。 （3）获取异步任务完成后的执行结果。

    //callable实例属性用来保存并发执行的Callable<V>类型的任务，并 且callable实例属性需要在FutureTask实例构造时进行初始化。
    //FutureTask类实现了Runnable接口，在其run()方法的实现版本中会执行 callable成员的call()方法。
    //FutureTask的outcome实例属性用于保存callable成员call()方法的异 步执行结果。在FutureTask类的run()方法完成callable成员的call()方法的 执行之后，其结果将被保存在outcome实例属性中，供FutureTask类的 get()方法获取。

    //阻塞性的获取接口

    public  static final  int MAX = 5;
    public static final int COMPUTER_TIME = 1000;

    static class CallableTask implements Callable<Long> {

        @Override
        public Long call() throws Exception {
            long l = System.currentTimeMillis();
            System.out.println("start " + Thread.currentThread());
            Thread.sleep(1000);
            for (int i = 0; i < COMPUTER_TIME; i++) {
                int j = i * 100;
            }
            long l1 = System.currentTimeMillis();
            System.out.println(l1 - l);

            return l1 - l;
        }

        public static void main(String[] args) {
            CallableTask callableTask = new CallableTask();
            FutureTask<Long> longFutureTask = new FutureTask<>(callableTask);

            Thread thread = new Thread(longFutureTask);
            thread.start();

            Long aLong = null;
            try {
                aLong = longFutureTask.get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            System.out.println("aLong = " + aLong);
        }
    }

}
